﻿using AutoMapper;
using JunionRobotTaskManager.Dtos;
using JunionRobotTaskManager.Models;
using JunionRobotTaskManager.Repository;
using LazyCache;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using Redbus.Interfaces;
using SqlSugar;

namespace JunionRobotTaskManager.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class RobotController : ControllerBase
    {
        #region Field
        private readonly ILogger<RobotController> _logger;

        private readonly IRobotRepository _robotRepository;

        private readonly IEventBus _eventBus;
        #endregion


        public RobotController(
            ILogger<RobotController> logger,
            IRobotRepository robotRepository,
            IEventBus mCache)
        {
            _logger = logger;
            _robotRepository = robotRepository;
            _eventBus = mCache;
        }


        #region 创建

        /// <summary>
        /// 创建机器人
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Create([FromServices] IMapper iMapper, RobotDto robotDto)
        {
            try
            {
                var robot = iMapper.Map<Robot>(robotDto);
               
                if (!await _robotRepository.AddAsync(robot))
                    return ApiResultHelper.Error("添加失败，服务器发生错误");
                else
                    _eventBus.Publish<BusMessage>(BusMessage.AddCreate("Robot", robot));
                return ApiResultHelper.Success(robot);
            }
            catch (Exception ex)
            {
                return ApiResultHelper.Error($"添加出错!服务器发生错误:{ex.Message}");
            }
        }

        public async Task<ActionResult<ApiResult>> Import([FromServices] IMapper iMapper, List<RobotDto> robotDtos)
        {
            try
            {
                var robots = iMapper.Map<List<Robot>>(robotDtos);

                 var ids=robots.Select(x=>x.Id).ToList();
                 var existsId= _robotRepository.Query(x => ids.Contains(x.Id)).Select(x=>x.Id);
                var upRobots= robots.Where(x=>existsId.Contains(x.Id)).ToList();
                var addRobots = robots.Where(x => !existsId.Contains(x.Id)).ToList();

                if(upRobots.Any())
                {
                    if (!await _robotRepository.UpdateListAsync(upRobots))
                        return ApiResultHelper.Error("添加失败，服务器发生错误");
                }
                
                if(addRobots.Any())
                {
                    if (!await _robotRepository.AddListAsync(addRobots))
                        return ApiResultHelper.Error("添加失败，服务器发生错误");
                }
               
                
                return ApiResultHelper.Success(0);
            }
            catch (Exception ex)
            {
                return ApiResultHelper.Error($"添加出错!服务器发生错误:{ex.Message}");
            }
        }
        #endregion

        #region 更新

        /// <summary>
        /// 更新机器人
        /// </summary>
        /// <param name="robotId">机器人的Id</param>
        /// <param name="newrobot">新的机器人信息</param>
        /// <returns></returns>
        [HttpPut("{robotId}")]
        public async Task<ActionResult<ApiResult>> Update([FromServices] IMapper iMapper, [FromRoute] string robotId, RobotDto newrobot)
        {

            if (!_robotRepository.CheckExist(x=>x.Id==robotId)) 
                return ApiResultHelper.Error("没有找到该机器人");
            var updatedRobot = iMapper.Map<Robot>(newrobot);
            bool b = await _robotRepository.UpdateEntityAsync(updatedRobot);
            if (!b)
                return ApiResultHelper.Error("修改失败");
            else
                _eventBus.Publish<BusMessage>( BusMessage.UpdateCreate("Robot",  updatedRobot));

            return ApiResultHelper.Success(newrobot);
        }

        /// <summary>
        /// 启用/禁用机器人
        /// </summary>
        /// <returns></returns>
        [HttpPatch("{id}/{enable}")]
        public async Task<ActionResult<ApiResult>> Enable(string id, bool enable)
        {
            var robot = await _robotRepository.FindByIdAsync(id);
            if (robot == null) 
                return ApiResultHelper.Error("没有找到机器人");
            robot.Enable = enable;

            bool b = await _robotRepository.UpdateEntityAsync(robot);
            if (!b)
                return ApiResultHelper.Error("修改失败");
            else
                _eventBus.Publish<BusMessage>(BusMessage.UpdateCreate("Robot", robot));
            return ApiResultHelper.Success(robot);
        }

        /// <summary>
        /// 是否在电梯里
        /// </summary>
        /// <returns></returns>
        [HttpPatch("{id}/{inElevator}")]
        public async Task<ActionResult<ApiResult>> InElevator(string id, bool inElevator)
        {
            var robot = await _robotRepository.FindByIdAsync(id);
            if (robot == null)
                return ApiResultHelper.Error("没有找到机器人");
            robot.InElevator = inElevator;

            bool b = await _robotRepository.UpdateEntityAsync(robot);
            if (!b)
                return ApiResultHelper.Error("修改失败");
            else
                _eventBus.Publish<BusMessage>(BusMessage.UpdateCreate("Robot", robot));
            return ApiResultHelper.Success(robot);
        }
        #endregion

        #region 删除

        /// <summary>
        /// 删除机器人
        /// </summary>
        /// <param name="robotId">机器人的Id</param>
        /// <returns></returns>
        [HttpDelete("{robotId}")]
        public async Task<ActionResult<ApiResult>> Delete(string robotId)
        {

            if (!await _robotRepository.DeleteByIdAsync(robotId))
                return ApiResultHelper.Error("删除失败");
            else
                _eventBus.Publish<BusMessage>(BusMessage.DeleteCreate("Robot",  new string[] { robotId }));

            return ApiResultHelper.Success("true");
        }

        /// <summary>
        /// 批量删除机器人
        /// </summary>
        /// <param name="ids">要删除的所有ids</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ActionResult<ApiResult>> DeleteByIds(string[] ids)
        {
            bool b = await _robotRepository.DeleteByIdsAsync(ids);
            if (!b)
                return ApiResultHelper.Error("删除失败");
            else
                _eventBus.Publish<BusMessage>(new BusMessage("Robot", Operation.Delete, ids));

            return ApiResultHelper.Success(b);
        }
        #endregion

        #region 查找

        /// <summary>
        /// 分页查找任务
        /// </summary>
        /// <param name="page">分页数</param>
        /// <param name="limit">行数</param>
        /// <param name="query">筛选条件</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetRobotsByPage([FromServices] IMapper iMapper, int page, int limit, [FromQuery] string query)
        {
            RefAsync<int> total = 0;
            try
            {

                if (query != null)
                {
                    JObject jobject = JObject.Parse(query);
                    List<IConditionalModel> models = new List<IConditionalModel>();

                    foreach (var key in jobject.Properties())
                    {
                        models.Add(new ConditionalModel()
                        { FieldName = key.Name, FieldValue = key.Value.ToString(), ConditionalType = ConditionalType.Equal });
                    }


                    var robots = await _robotRepository.QueryAsync(models, page, limit, total);
                    List<RobotDto> robotDtos = iMapper.Map<List<RobotDto>>(robots);
                    return ApiResultHelper.Success(robotDtos, total);
                }
                else
                {
                    var robots = await _robotRepository.QueryAsync(page, limit, total);
                    List<RobotDto> robotDtos = iMapper.Map<List<RobotDto>>(robots);
                    return ApiResultHelper.Success(robotDtos, total);
                }


            }
            catch (Exception ex)
            {
                return ApiResultHelper.Error($"查询出错:{ex.Message}");
            }


        }

        /// <summary>
        /// 获取实时信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ApiResult GetRealRobotInfo([FromServices] IAppCache _cache, int page, int limit)
        {




            RefAsync<int> totalRobot = 0;
            List<Robot> realRobots = null;
            _cache.TryGetValue<List<Robot>>("Robots", out realRobots);
            if (realRobots != null)
            {

                totalRobot = realRobots.Count();
                return ApiResultHelper.Success(realRobots.Skip(limit * (page - 1)).Take(limit).ToList(), totalRobot);

            }
            else
            {
                return ApiResultHelper.Error("未找到");
            }

        }

        /// <summary>
        /// 校验信息是否唯一
        /// </summary>
        /// <param name="query">ip="1312321"or id="xxx"</param>
        /// <returns></returns>
        [HttpGet("{query}")]
        public async Task<ActionResult<ApiResult>> Check(string query)
        {
            string currentmsg = query.Split('=', StringSplitOptions.None)[1];
            try
            {
                if (query.Contains("ip"))
                {
                    var data = await _robotRepository.QueryAsync(x => x.IP == currentmsg);
                    return ApiResultHelper.Success(data.Count);
                }
                else if (query.Contains("id"))
                {
                    var data = await _robotRepository.QueryAsync(x => x.Id == currentmsg);
                    return ApiResultHelper.Success(data.Count);
                }
                else
                {
                    return ApiResultHelper.Error("查询字符串不对");
                }

            }
            catch (Exception e)
            {
                return ApiResultHelper.Error("查找机器人出错" + e.Message);
            }

        }

        /// <summary>
        /// 查找iP和id
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetRobotInfos()
        {

            var devices = await _robotRepository.QueryAsync();
            var info = devices.Select(x => new { x.Name, x.Id });
            return ApiResultHelper.Success(info);
        }
        #endregion

    }
}
